package org.Yiran.timetale_re.block.crystal.base;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.AmethystClusterBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.level.ItemLike;
import org.Yiran.timetale_re.item.ItemsRegister;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nullable;

/**
 * 水晶方块基类
 * <p>
 * 这个类是所有水晶方块的基类，提供了通用的属性和方法。
 * 每个水晶方块都有等级属性，表示其强度等级。
 * </p>
 */
public abstract class CrystalBaseBlock extends AmethystClusterBlock {
    
    // 调试模式开关，为true时加速生长
    private static boolean debugMode = false;
    
    /**
     * 构造函数
     */
    public CrystalBaseBlock() {
        super(7,
                3,
                BlockBehaviour.
                        Properties.copy(Blocks.AMETHYST_CLUSTER)
                        .lightLevel((state) -> 5)
                        .strength(1.5f, 3.0f)
                        .noOcclusion()
                        .isViewBlocking((state, level, pos) -> false)
        );
    }

    /**
     * 创建方块状态定义
     * 
     * @param builder 状态定义构建器
     */
    @Override
    protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
        builder.add(FACING, getLevelProperty(), BlockStateProperties.WATERLOGGED);
    }

    /**
     * 根据方块状态获取光照等级
     *
     * @param state 方块状态
     * @param levelProperty 等级属性
     * @return 光照等级 (0-15)
     */
    protected static int getLightLevel(BlockState state, IntegerProperty levelProperty) {
        return state.getValue(levelProperty) * 3;
    }

    /**
     * 获取放置时的方块状态
     * 
     * @param context 放置上下文
     * @return 方块状态
     */
    @Override
    public BlockState getStateForPlacement(@NotNull net.minecraft.world.item.context.BlockPlaceContext context) {
        // 获取放置方向
        Direction direction = context.getClickedFace();
        
        // 获取放置位置的方块状态
        BlockState state = context.getLevel().getBlockState(context.getClickedPos().relative(direction.getOpposite()));
        
        // 如果放置位置的方块状态已经是该方块且等级小于最大等级，则升级等级
        if (state.is(this)) {
            IntegerProperty levelProperty = getLevelProperty();
            int currentLevel = state.getValue(levelProperty);
            int maxLevel = levelProperty.getPossibleValues().stream().max(Integer::compareTo).orElse(3);
            if (currentLevel < maxLevel) {
                return state.setValue(levelProperty, currentLevel + 1);
            }
        }
        
        // 否则返回默认状态
        return defaultBlockState()
                .setValue(FACING, direction)
                .setValue(getLevelProperty(), 1)
                .setValue(BlockStateProperties.WATERLOGGED, 
                         context.getLevel().getFluidState(context.getClickedPos()).getType() == net.minecraft.world.level.material.Fluids.WATER);
    }

    /**
     * 获取等级属性
     * 
     * @return 等级属性
     */
    public abstract IntegerProperty getLevelProperty();

    /**
     * 获取掉落物品
     * 
     * @return 掉落物品
     */
    public abstract Item getDropItem();

    /**
     * 获取放置时的物品
     * 
     * @param level 世界
     * @param pos 位置
     * @param state 方块状态
     * @return 物品栈
     */
    @Override
    public @NotNull ItemStack getCloneItemStack(@NotNull BlockGetter level, @NotNull BlockPos pos, @NotNull BlockState state) {
        return new ItemStack(getDropItem());
    }

    /**
     * 随机滴落（用于生长）
     * 
     * @param state 方块状态
     * @param level 服务端世界
     * @param pos 位置
     * @param random 随机数生成器
     */
    @Override
    public void randomTick(@NotNull BlockState state, @NotNull ServerLevel level, @NotNull BlockPos pos, @NotNull RandomSource random) {
        // 如果是调试模式或随机数满足条件且可以生长，则尝试生长
        if ((debugMode || random.nextInt(10) == 0) && canGrow(state, level, pos)) {
            grow(state, level, pos);
        }
    }

    /**
     * 生长方法
     * 
     * @param state 方块状态
     * @param level 世界
     * @param pos 位置
     */
    protected void grow(BlockState state, ServerLevel level, BlockPos pos) {
        // 获取当前等级和最大等级
        IntegerProperty levelProperty = getLevelProperty();
        int currentLevel = state.getValue(levelProperty);
        int maxLevel = getMaxGrowthLevel();
        
        // 如果当前等级小于最大等级，则升级
        if (currentLevel < maxLevel) {
            level.setBlock(pos, state.setValue(levelProperty, currentLevel + 1), Block.UPDATE_ALL);
        }
    }
    
    /**
     * 检查水晶是否可以生长
     * 子类可以重写此方法以实现特定的生长条件
     * 
     * @param state 方块状态
     * @param level 世界对象
     * @param pos 方块位置
     * @return 是否可以生长
     */
    protected boolean canGrow(BlockState state, ServerLevel level, BlockPos pos) {
        // 默认情况下，所有水晶都不能生长，需要子类重写以实现特定的生长条件
        return false;
    }
    
    /**
     * 获取水晶的最大生长等级
     * 子类可以重写此方法以实现不同的最大等级
     * 
     * @return 最大生长等级
     */
    protected int getMaxGrowthLevel() {
        // 通过获取等级属性的可能值中的最大值来动态确定最大生长等级
        return this.getLevelProperty().getPossibleValues().stream()
                .max(Integer::compareTo)
                .orElse(3); // 如果无法获取最大值，则默认为3
    }
    
    /**
     * 设置调试模式
     * 
     * @param debug 调试模式开关
     */
    public static void setDebugMode(boolean debug) {
        debugMode = debug;
    }
    
    /**
     * 获取调试模式状态
     * 
     * @return 调试模式开关
     */
    public static boolean isDebugMode() {
        return debugMode;
    }
}